package org.feng.fxfront.pages.animal;

import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.TableView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import lombok.Builder;
import lombok.Data;
import org.feng.api.PageBean;
import org.feng.api.ResultVo;
import org.feng.api.animal.constant.AnimalSexEnum;
import org.feng.api.animal.constant.AnimalTypeEnum;
import org.feng.api.animal.request.AddAndUpdateAnimalRequest;
import org.feng.api.animal.request.DeleteAnimalRequest;
import org.feng.api.animal.request.QueryAnimalRequest;
import org.feng.api.animal.response.AddAndUpdateAnimalDto;
import org.feng.api.animal.response.DeleteAnimalDto;
import org.feng.api.animal.response.QueryAnimalVo;
import org.feng.api.animal.service.AnimalApi;
import org.feng.api.sys.annotations.PageNodeKey;
import org.feng.fxfront.StartApplication;
import org.feng.fxfront.client.AnimalHttpClient;
import org.feng.fxfront.pages.components.CustomPagingComponent;
import org.feng.fxfront.pages.components.CustomTableViewComponent;
import org.feng.fxfront.pages.components.LogTextAreaComponent;
import org.feng.fxfront.sys.PageNodeRender;
import org.feng.fxfront.util.ControlUtil;
import org.feng.fxfront.util.StyleUtil;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * 动物管理界面
 *
 * @author feng
 */
@PageNodeKey(value = AnimalManagePage.PAGE_KEY, pageName = "动物管理")
public class AnimalManagePage implements PageNodeRender {
    public static final String PAGE_KEY = "animalManage";

    /**
     * 整体页面布局宽度
     */
    private static final double WIDTH = ((StartApplication.SCREEN_WIDTH * 0.8) - StartApplication.LEFT_MENU_WIDTH) * 0.8;

    private final static AnimalApi ANIMAL_API = new AnimalHttpClient();

    public AnimalManagePage() {
    }

    @Override
    public Node render(Pane pane) {
        // 整体竖型布局
        VBox vbox = new VBox();
        // 当前容器内，布局居中，局上
        vbox.setAlignment(Pos.TOP_CENTER);
        // 当前面板背景颜色
        StyleUtil.setPaneBackground(vbox, Color.web("#fffff0"));
        // 页面标题
        vbox.getChildren().add(genPageTitle("动物管理页面"));

        // 操作按钮组
        AnimalOperationButtonGroup operationButtonGroup = new AnimalOperationButtonGroup(250, WIDTH);
        vbox.getChildren().add(operationButtonGroup.getButtonGroupVbox());
        //  搜索面板
        SearchAnimalPane searchAnimalPane = new SearchAnimalPane(WIDTH);
        vbox.getChildren().add(searchAnimalPane.getSearchPane());
        // 分页组件
        CustomPagingComponent customPagingComponent = new CustomPagingComponent(WIDTH, 60);
        // 控制台输入操作记录
        LogTextAreaComponent logger = new LogTextAreaComponent(400, WIDTH);
        // 表格视图&分页查数据
        PageBean<QueryAnimalVo> pageBean = queryAnimalVoPageBean(searchAnimalPane, customPagingComponent);
        List<QueryAnimalVo> tableDataList = Objects.nonNull(pageBean) ? pageBean.getData() : Collections.emptyList();
        CustomTableViewComponent<QueryAnimalVo> tableViewComponent = new CustomTableViewComponent<>(QueryAnimalVo.class, tableDataList);
        TableView<QueryAnimalVo> animalTableView = tableViewComponent.getTableView();
        // 表格展示数据+分页
        vbox.getChildren().add(animalTableView);
        vbox.getChildren().add(customPagingComponent.getPagingGridPane());
        // 分隔线
        vbox.getChildren().add(ControlUtil.separator(animalTableView.getMaxWidth()));
        // 操作记录
        vbox.getChildren().add(logger.getLogBox());

        // 注册刷新
        operationButtonGroup.getRefreshButton().setOnAction(event -> ControlUtil.refreshTableView(animalTableView, logger));

        // 更改每页大小-事件处理
        customPagingComponent.getPageSize().setOnAction(new ModifyPageSizeEventHandler.ModifyPageSizeEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .build()
        );

        // 上一页-点击事件处理
        customPagingComponent.getLastPageButton().setOnAction(new SkipPageClickEventHandler.SkipPageClickEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .skipPreviousPage(true)
                .build());

        // 下一页
        customPagingComponent.getNextPageButton().setOnAction(new SkipPageClickEventHandler.SkipPageClickEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .skipNextPage(true)
                .build());

        // 首页事件
        customPagingComponent.getFirstPageButton().setOnAction(new SkipPageClickEventHandler.SkipPageClickEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .skipFirstPage(true)
                .build());

        // 最后一页
        customPagingComponent.getFinallyPageButton().setOnAction(new SkipPageClickEventHandler.SkipPageClickEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .skipFinalPage(true)
                .build());

        // 跳转事件
        customPagingComponent.getSkipPageButton().setOnAction(new SkipPageClickEventHandler.SkipPageClickEventHandlerBuilder()
                .searchAnimalPane(searchAnimalPane)
                .customPagingComponent(customPagingComponent)
                .tableViewComponent(tableViewComponent)
                .logger(logger)
                .build());

        // 当选择发生变化时调用该函数-选择某一行时
        animalTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null && !animalTableView.getSelectionModel().isSelected(Math.toIntExact(newVal.getId()))) {
                logger.log("已选择 " + newVal.getName());
            }
        });

        // 注册搜索
        searchAnimalPane.getSearchButton().setOnAction(event -> {
            PageBean<QueryAnimalVo> queryAnimalVoPageBean = refreshToFirstPage(searchAnimalPane, customPagingComponent);
            logger.log("搜索成功！");
            // 刷新列表
            tableViewComponent.resetData(queryAnimalVoPageBean.getData());
            ControlUtil.refreshTableView(animalTableView, logger);
        });

        // 注册删除
        operationButtonGroup.getDeleteButton().setOnAction(ControlUtil.alertConfirm("确认删除吗？", "", buttonType -> {
            ButtonBar.ButtonData buttonData = buttonType.getButtonData();
            if (buttonData.isDefaultButton()) {
                // 确认删除
                ObservableList<QueryAnimalVo> items = animalTableView.getSelectionModel().getSelectedItems();
                List<Long> ids = items.stream().map(QueryAnimalVo::getId).toList();
                logger.log("正在删除 " + items.stream().map(QueryAnimalVo::getName).collect(Collectors.joining(",")));
                DeleteAnimalRequest deleteAnimalRequest = new DeleteAnimalRequest();
                deleteAnimalRequest.setIds(ids);
                ResultVo<DeleteAnimalDto> resultVo = ANIMAL_API.deleteAnimal(deleteAnimalRequest);
                if (!resultVo.requestSuccess()) {
                    logger.log("删除 " + items.stream().map(QueryAnimalVo::getName).collect(Collectors.joining(",")) + "失败！失败原因如下："+ resultVo.getMessage());
                    return;
                }

                // 刷新列表
                PageBean<QueryAnimalVo> queryAnimalVoPageBean = refreshToFirstPage(searchAnimalPane, customPagingComponent);
                tableViewComponent.resetData(queryAnimalVoPageBean.getData());
                ControlUtil.refreshTableView(animalTableView, logger);
                logger.log("删除 " + items.stream().map(QueryAnimalVo::getName).collect(Collectors.joining(",")) + "成功！");
            }
        }));

        // 注册新增
        operationButtonGroup.getAddButton().setOnAction(event -> {
            AddAndUpdateAnimalDialog addDialog = new AddAndUpdateAnimalDialog(null);
            addDialog.getDialog().showAndWait().ifPresent(buttonType -> {
                if (buttonType.getButtonData().isDefaultButton()) {
                    // 获取文本框中数据
                    AddAndUpdateAnimalRequest addAnimalRequest = addDialog.genAddAndUpdateAnimalRequest();
                    logger.log("正在新增 " + addAnimalRequest.getName());
                    // 添加动物
                    ResultVo<AddAndUpdateAnimalDto> resultVo = ANIMAL_API.addAnimal(addAnimalRequest);
                    if (!resultVo.requestSuccess()) {
                        logger.log("新增 " + addAnimalRequest.getName() + "失败！失败原因如下：" + resultVo.getMessage());
                        return;
                    }

                    logger.log("新增 " + addAnimalRequest.getName() + "成功！");
                    // 刷新列表
                    PageBean<QueryAnimalVo> queryAnimalVoPageBean = refreshToFirstPage(searchAnimalPane, customPagingComponent);
                    tableViewComponent.resetData(queryAnimalVoPageBean.getData());
                    ControlUtil.refreshTableView(animalTableView, logger);

                }
            });
            addDialog.getDialog().close();
        });

        // 注册更新
        operationButtonGroup.getUpdateButton().setOnAction(event -> {
            ObservableList<QueryAnimalVo> selectedItems = animalTableView.getSelectionModel().getSelectedItems();
            if (selectedItems == null || selectedItems.size() != 1) {
                logger.log("请选择一条数据进行修改");
                return;
            }
            // 获取选中的数据原值
            QueryAnimalVo selectedAnimal = selectedItems.get(0);
            AddAndUpdateAnimalDialog updateDialog = new AddAndUpdateAnimalDialog(selectedAnimal);
            // 注册点击事件
            updateDialog.getDialog().showAndWait().ifPresent(buttonType -> {
                if (buttonType.getButtonData().isDefaultButton()) {
                    logger.log("开始修改数据");
                    // 获取文本框中数据
                    AddAndUpdateAnimalRequest updateAnimalRequest = updateDialog.genAddAndUpdateAnimalRequest();
                    updateAnimalRequest.setId(selectedAnimal.getId());

                    logger.log(String.format("正在修改ID为【%s】,名字为【%s】 ", selectedAnimal.getId(), updateDialog.getOldAnimal().getName()));

                    // 更新动物
                    ResultVo<AddAndUpdateAnimalDto> resultVo = ANIMAL_API.updateAnimal(updateAnimalRequest);
                    if (!resultVo.requestSuccess()) {
                        logger.log("修改 " + updateAnimalRequest.getName() + "失败！失败原因如下：" + resultVo.getMessage());
                        return;
                    }
                    // 刷新列表
                    PageBean<QueryAnimalVo> queryAnimalVoPageBean = refreshToFirstPage(searchAnimalPane, customPagingComponent);
                    tableViewComponent.resetData(queryAnimalVoPageBean.getData());
                    ControlUtil.refreshTableView(animalTableView, logger);

                    logger.log(String.format("修改完成! ID为【%s】，修改名字【%s】为【%s】，动物类型【%s】为【%s】，动物性别【%s】为【%s】，年龄【%s】为【%s】", selectedAnimal.getId(),
                            updateDialog.getOldAnimal().getName(), updateAnimalRequest.getName(),
                            updateDialog.getOldAnimal().getAnimalTypeName(), AnimalTypeEnum.getByCode(updateAnimalRequest.getAnimalTypeCode()).getDesc(),
                            updateDialog.getOldAnimal().getAnimalSexName(), AnimalSexEnum.getByCode(updateAnimalRequest.getAnimalSexCode()).getDesc(),
                            updateDialog.getOldAnimal().getAge(), updateAnimalRequest.getAge()));
                }
            });
            updateDialog.getDialog().close();
        });

        // 动物管理页面初始化完成，刷新一次
        ControlUtil.refreshTableView(animalTableView, logger);
        return vbox;
    }

    /**
     * 刷新列表数据至第一页
     */
    private PageBean<QueryAnimalVo> refreshToFirstPage(SearchAnimalPane searchAnimalPane, CustomPagingComponent customPagingComponent) {
        customPagingComponent.setCurrentPageValue(1);
        return queryAnimalVoPageBean(searchAnimalPane, customPagingComponent);
    }

    private static PageBean<QueryAnimalVo> queryAnimalVoPageBean(SearchAnimalPane searchAnimalPane, CustomPagingComponent customPagingComponent) {
        return queryAnimalVoPageBean(searchAnimalPane, customPagingComponent, null);
    }

    private static PageBean<QueryAnimalVo> queryAnimalVoPageBean(SearchAnimalPane searchAnimalPane, CustomPagingComponent customPagingComponent, Consumer<CustomPagingComponent> cconsumer) {
        if (cconsumer != null) {
            cconsumer.accept(customPagingComponent);
        }
        QueryAnimalRequest queryAnimalRequest = searchAnimalPane.genQueryAnimalRequest(customPagingComponent.getPageSizeValue(), customPagingComponent.getCurrentPageValue());
        ResultVo<PageBean<QueryAnimalVo>> resultVo = ANIMAL_API.queryAnimal(queryAnimalRequest);
        if (resultVo != null && Objects.equals(0, resultVo.getCode()) && resultVo.getData() != null) {
            customPagingComponent.setPageCountValue(resultVo.getData().getPages());
            return resultVo.getData();
        }
        return new PageBean<>();
    }

    /**
     * 修改每页大小事件处理器
     */
    @Builder
    @Data
    private static class ModifyPageSizeEventHandler implements EventHandler<ActionEvent> {

        private CustomTableViewComponent<QueryAnimalVo> tableViewComponent;
        private CustomPagingComponent customPagingComponent;
        private SearchAnimalPane searchAnimalPane;
        private LogTextAreaComponent logger;

        @Override
        public void handle(ActionEvent actionEvent) {
            customPagingComponent.setCurrentPageValue(1);
            PageBean<QueryAnimalVo> modifyPageSizeTriggerQueryPageBean = queryAnimalVoPageBean(searchAnimalPane, customPagingComponent);
            assert modifyPageSizeTriggerQueryPageBean != null;
            int pageSize = modifyPageSizeTriggerQueryPageBean.getPageSize();
            // 重新计算页数
            customPagingComponent.setPageCountValue(modifyPageSizeTriggerQueryPageBean.getPages());
            logger.log(String.format("修改每页大小为：%s，重新刷新列表！", pageSize));

            // 刷新列表
            tableViewComponent.resetData(modifyPageSizeTriggerQueryPageBean.getData());
            ControlUtil.refreshTableView(tableViewComponent.getTableView(), logger);
        }
    }

    /**
     * 跳转页面-事件处理器
     */
    @Builder
    @Data
    private static class SkipPageClickEventHandler implements EventHandler<ActionEvent> {

        private CustomTableViewComponent<QueryAnimalVo> tableViewComponent;
        private CustomPagingComponent customPagingComponent;
        private SearchAnimalPane searchAnimalPane;
        private LogTextAreaComponent logger;

        private Integer customSkipPageNum;
        /**
         * 跳转首页
         */
        private boolean skipFirstPage;
        /**
         * 跳转最后一页
         */
        private boolean skipFinalPage;

        /**
         * 跳转下一页
         */
        private boolean skipNextPage;
        /**
         * 跳转上一页
         */
        private boolean skipPreviousPage;

        @Override
        public void handle(ActionEvent actionEvent) {
            int currentPage = customPagingComponent.getCurrentPageValue();
            if (skipFirstPage) {
                customSkipPageNum = 1;
            }
            if (skipFinalPage) {
                customSkipPageNum = customPagingComponent.getPageCountValue();
            }
            if (skipPreviousPage) {
                customSkipPageNum = customPagingComponent.getCurrentPageValue() - 1;
            }
            if (skipNextPage) {
                customSkipPageNum = customPagingComponent.getCurrentPageValue() + 1;
            }

            if (Objects.nonNull(customSkipPageNum)) {
                currentPage = customSkipPageNum;
                customPagingComponent.setCurrentPageValue(currentPage);
            }

            // 修复页面最小边界
            if (currentPage < 1) {
                customPagingComponent.setCurrentPageValue(1);
                logger.log("要跳转的页面不能小于1，已经修复数据，即将跳转到第【1】页");

            }
            // 修复页面最大边界
            if (currentPage > customPagingComponent.getPageCountValue()) {
                customPagingComponent.setCurrentPageValue(customPagingComponent.getPageCountValue());
                logger.log("要跳转的页面不能大于总页数，已经修复数据，即将跳转到最后一页");
            }
            // 分页查数据
            PageBean<QueryAnimalVo> skipPageClickTriggerQueryPageBean = queryAnimalVoPageBean(searchAnimalPane, customPagingComponent);
            logger.log(String.format("当前显示为第【%s】页", customPagingComponent.getCurrentPageValue()));
            assert skipPageClickTriggerQueryPageBean != null;
            // 刷新列表
            tableViewComponent.resetData(skipPageClickTriggerQueryPageBean.getData());
            ControlUtil.refreshTableView(tableViewComponent.getTableView(), logger);
        }
    }
}
